//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.yeye.studio.response;

import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.util.Optional;


/**
 * 返回信息
 *
 * @param <T>
 */
public class Res<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 状态码
     */
    private int code;
    /**
     * 是否成功
     */
    private boolean success;
    /**
     * 承载数据
     */
    private T data;
    /**
     * 返回消息
     */
    private String msg;

    private Res(IResultCode resultCode) {
        this(resultCode, null, resultCode.getMessage());
    }

    private Res(IResultCode resultCode, String msg) {
        this(resultCode, null, msg);
    }

    private Res(IResultCode resultCode, T data) {
        this(resultCode, data, resultCode.getMessage());
    }

    private Res(IResultCode resultCode, T data, String msg) {
        this(resultCode.getCode(), data, msg);
    }

    private Res(int code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
        this.success = ResultCode.SUCCESS.code == code;
    }

    public Res() {
    }

    /**
     * 成功
     *
     * @param result
     * @return
     */
    public static boolean isSuccess(@Nullable Res<?> result) {
        return (Boolean) Optional.ofNullable(result).map((x) -> {
            return ObjectUtils.nullSafeEquals(ResultCode.SUCCESS.code, x.code);
        }).orElse(Boolean.FALSE);
    }

    /**
     * 没有成功
     *
     * @param result
     * @return
     */
    public static boolean isNotSuccess(@Nullable Res<?> result) {
        return !isSuccess(result);
    }

    public static <T> Res<T> data(T data) {
        return data(data, "操作成功");
    }

    public static <T> Res<T> data(T data, String msg) {
        return data(200, data, msg);
    }

    public static <T> Res<T> data(int code, T data, String msg) {
        return new Res(code, data, data == null ? "暂无承载数据" : msg);
    }

    public static <T> Res<T> success(String msg) {
        return new Res(ResultCode.SUCCESS, msg);
    }

    public static <T> Res<T> success(IResultCode resultCode) {
        return new Res(resultCode);
    }

    public static <T> Res<T> success(IResultCode resultCode, String msg) {
        return new Res(resultCode, msg);
    }

    /**
     * 失败返回信息
     *
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> Res<T> fail(String msg) {
        return new Res(ResultCode.FAILURE, msg);
    }

    /**
     * 失败返回状态码和失败信息
     *
     * @param code
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> Res<T> fail(int code, String msg) {
        return new Res(code, (Object) null, msg);
    }

    /**
     * 失败返回状态对象
     *
     * @param resultCode
     * @param <T>
     * @return
     */
    public static <T> Res<T> fail(IResultCode resultCode) {
        return new Res(resultCode);
    }

    /**
     * 失败返回状态对象和失败信息
     *
     * @param resultCode
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> Res<T> fail(IResultCode resultCode, String msg) {
        return new Res(resultCode, msg);
    }

    public int getCode() {
        return this.code;
    }

    public boolean isSuccess() {
        return this.success;
    }

    public T getData() {
        return this.data;
    }

    public String getMsg() {
        return this.msg;
    }

    public void setCode(final int code) {
        this.code = code;
    }

    public void setSuccess(final boolean success) {
        this.success = success;
    }

    public void setData(final T data) {
        this.data = data;
    }

    public void setMsg(final String msg) {
        this.msg = msg;
    }

    /**
     * 返回状态
     *
     * @param flag 布尔类型
     * @param <T>
     * @return 操作成功/失败
     */
    public static <T> Res<T> status(boolean flag) {
        return flag ? success("操作成功") : fail("操作失败");
    }

    @Override
    public String toString() {
        return "Res(code=" + this.getCode() + ", success=" + this.isSuccess() + ", data=" + this.getData() + ", msg=" + this.getMsg() + ")";
    }
}
